package boundary;

import java.awt.Color;
import java.awt.Component;
import java.util.List;
import javax.swing.JList;
import javax.swing.JTextPane;
import javax.swing.ListCellRenderer;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
import dataview.CiboVis;
import dataview.MenuVis;
import dataview.RicettaVis;
import dataview.TipoTermine;
import store.Cibo;
import store.Menu;
import store.Ricetta;

class MyListCellRenderer extends JTextPane implements ListCellRenderer {
	private static final long serialVersionUID = 2186026188156020493L;
	protected Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
	private Border SAFE_NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1);
	private boolean completo = true;
	
	public MyListCellRenderer(boolean completo) {
		super();
		this.completo = completo;
		setOpaque(true);
		setBorder(getNoFocusBorder());
	}
	
	@Override
	public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
		setComponentOrientation(list.getComponentOrientation());
		Color bg = null;
		Color fg = null;
		
		JList.DropLocation dropLocation = list.getDropLocation();
		if (dropLocation != null && !dropLocation.isInsert() && dropLocation.getIndex() == index) {
			
			bg = UIManager.getColor("List.dropCellBackground");
			fg = UIManager.getColor("List.dropCellForeground");
			
			isSelected = true;
		}
		
		if (isSelected) {
			setBackground(bg == null ? list.getSelectionBackground() : bg);
			setForeground(fg == null ? list.getSelectionForeground() : fg);
		} else {
			if (index % 2 == 1)
				setBackground(list.getBackground());
			else setBackground(new Color(235, 235, 235));
			setForeground(list.getForeground());
		}
		
		JTextPane textPane = new JTextPane();
		StyledDocument doc = textPane.getStyledDocument();
		addStylesToDocument(doc);
		setDocument(doc);
		
		if (value instanceof Cibo) {
			try {
				CiboVis cv = ((Cibo)value).vis();
				doc.insertString(doc.getLength(), "Nome Cibo: ", doc.getStyle("italic"));
				doc.insertString(doc.getLength(), cv.getNome() + "\n", doc.getStyle("bold"));
				doc.insertString(doc.getLength(), "Descrizione: ", doc.getStyle("italic"));
				doc.insertString(doc.getLength(), cv.getDescrizione(), doc.getStyle("regular"));
				if (completo) {
					doc.insertString(doc.getLength(), "\nGenere Cibo: ", doc.getStyle("italic"));
					doc.insertString(doc.getLength(), listToString(cv.getTags()) + "\n", doc.getStyle("regular"));
					doc.insertString(doc.getLength(), "Calorie: ", doc.getStyle("italic"));
					doc.insertString(doc.getLength(), cv.getCalorie() + "\n", doc.getStyle("regular"));
					doc.insertString(doc.getLength(), "Composizione: ", doc.getStyle("italic"));
					doc.insertString(doc.getLength(), cv.getComposizione(), doc.getStyle("regular"));
				}
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
		} else if (value instanceof Ricetta) {
			try {
				RicettaVis rv = ((Ricetta)value).vis();
				doc.insertString(doc.getLength(), "Nome Ricetta: ", doc.getStyle("italic"));
				doc.insertString(doc.getLength(), rv.getNome() + "\n", doc.getStyle("bold"));
				doc.insertString(doc.getLength(), "Presentazione: ", doc.getStyle("italic"));
				doc.insertString(doc.getLength(), rv.getPresentazione(), doc.getStyle("regular"));
				if (completo) {
					doc.insertString(doc.getLength(), "\nNote: ", doc.getStyle("italic"));
					doc.insertString(doc.getLength(), rv.getNote() + "\n", doc.getStyle("regular"));
					doc.insertString(doc.getLength(), "Porzioni: ", doc.getStyle("italic"));
					doc.insertString(doc.getLength(), rv.getPorzioni() + "\n", doc.getStyle("regular"));
					doc.insertString(doc.getLength(), "Difficolta: ", doc.getStyle("italic"));
					doc.insertString(doc.getLength(), rv.getDifficolta() + "\n", doc.getStyle("regular"));
					if (!((Ricetta)value).getTag().getTerminiDiTipo(TipoTermine.tipo_preparazione).isEmpty()) {
						doc.insertString(doc.getLength(), "Tipo Preparazione: ", doc.getStyle("italic"));
						doc.insertString(doc.getLength(), ((Ricetta)value).getTag().getTerminiDiTipo(TipoTermine.tipo_preparazione) + "\n", doc.getStyle("regular"));
					}
					if (!((Ricetta)value).getTag().getTerminiDiTipo(TipoTermine.genere_cucina).isEmpty()) {
						doc.insertString(doc.getLength(), "Genere Cucina: ", doc.getStyle("italic"));
						doc.insertString(doc.getLength(), ((Ricetta)value).getTag().getTerminiDiTipo(TipoTermine.genere_cucina) + "\n", doc.getStyle("regular"));
					}
					if (!((Ricetta)value).getTag().getTerminiDiTipo(TipoTermine.genere_geografico).isEmpty()) {
						doc.insertString(doc.getLength(), "Genere Geografico: ", doc.getStyle("italic"));
						doc.insertString(doc.getLength(), ((Ricetta)value).getTag().getTerminiDiTipo(TipoTermine.genere_geografico) + "\n", doc.getStyle("regular"));
					}
					for (String val : rv.getValutazioni()) {
						doc.insertString(doc.getLength(), val.substring(0, val.indexOf(':')), doc.getStyle("italic"));
						doc.insertString(doc.getLength(), val.substring(val.indexOf(':'), val.length()) + "\n", doc.getStyle("regular"));
					}
					doc.insertString(doc.getLength(), "Ingredienti: ", doc.getStyle("italic"));
					doc.insertString(doc.getLength(), rv.getIngredienti() + "\n", doc.getStyle("regular"));
					doc.insertString(doc.getLength(), "Sottoricette: ", doc.getStyle("italic"));
					doc.insertString(doc.getLength(), rv.getSottoricette() + "\n", doc.getStyle("regular"));
					doc.insertString(doc.getLength(), "Procedimento: ", doc.getStyle("italic"));
					doc.insertString(doc.getLength(), listToString(rv.getProcedimento()), doc.getStyle("regular"));
				}
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
		} else if (value instanceof Menu) {
			try {
				MenuVis mv = ((Menu)value).vis();
				doc.insertString(doc.getLength(), "Nome Menu: ", doc.getStyle("italic"));
				doc.insertString(doc.getLength(), mv.getNome() + "\n", doc.getStyle("bold"));
				doc.insertString(doc.getLength(), "Data: ", doc.getStyle("italic"));
				doc.insertString(doc.getLength(), mv.getQuando() + "\n", doc.getStyle("regular"));
				doc.insertString(doc.getLength(), "Presentazione: ", doc.getStyle("italic"));
				doc.insertString(doc.getLength(), mv.getPresentazione(), doc.getStyle("regular"));
				
				if (completo) {
					doc.insertString(doc.getLength(), "\nNote: ", doc.getStyle("italic"));
					doc.insertString(doc.getLength(), mv.getNote() + "\n", doc.getStyle("regular"));
					doc.insertString(doc.getLength(), "Numero Persone: ", doc.getStyle("italic"));
					doc.insertString(doc.getLength(), mv.getNumPersone() + "\n", doc.getStyle("regular"));
					doc.insertString(doc.getLength(), "Difficolta: ", doc.getStyle("italic"));
					doc.insertString(doc.getLength(), mv.getDifficolta() + "\n", doc.getStyle("regular"));
					if (!((Menu)value).getTag().getTerminiDiTipo(TipoTermine.tipo_occasione).isEmpty()) {
						doc.insertString(doc.getLength(), "Tipo Occasione: ", doc.getStyle("italic"));
						doc.insertString(doc.getLength(), ((Menu)value).getTag().getTerminiDiTipo(TipoTermine.tipo_occasione) + "\n", doc.getStyle("regular"));
					}
					if (!((Menu)value).getTag().getTerminiDiTipo(TipoTermine.stagionalita).isEmpty()) {
						doc.insertString(doc.getLength(), "Stagionalita: ", doc.getStyle("italic"));
						doc.insertString(doc.getLength(), ((Menu)value).getTag().getTerminiDiTipo(TipoTermine.stagionalita) + "\n", doc.getStyle("regular"));
					}
					for (String val : mv.getValutazioni()) {
						doc.insertString(doc.getLength(), val.substring(0, val.indexOf(':')), doc.getStyle("italic"));
						doc.insertString(doc.getLength(), val.substring(val.indexOf(':'), val.length()) + "\n", doc.getStyle("regular"));
					}
					doc.insertString(doc.getLength(), "Portate: ", doc.getStyle("italic"));
					for (String portata : mv.getPortate()) {
						doc.insertString(doc.getLength(), "\n    " + portata, doc.getStyle("regular"));
					}
				}
			} catch (BadLocationException e) {
				e.printStackTrace();
			}
		}
		
		setEnabled(list.isEnabled());
		setFont(list.getFont());
		Border border = null;
		if (cellHasFocus) {
			if (isSelected) {
				border = UIManager.getBorder("List.focusSelectedCellHighlightBorder");
			}
			if (border == null) {
				border = UIManager.getBorder("List.focusCellHighlightBorder");
			}
		} else {
			border = getNoFocusBorder();
		}
		setBorder(border);
		return this;
	}
	
	private Border getNoFocusBorder() {
		if (System.getSecurityManager() != null) {
			return SAFE_NO_FOCUS_BORDER;
		} else {
			return noFocusBorder;
		}
	}
	
	@SuppressWarnings("unchecked")
	private String listToString(List lista) {
		String s = lista.toString();
		return s.substring(1, s.length() - 1);
	}
	
	protected void addStylesToDocument(StyledDocument doc) {
		Style def = StyleContext.getDefaultStyleContext().getStyle(StyleContext.DEFAULT_STYLE);
		
		Style regular = doc.addStyle("regular", def);
		StyleConstants.setFontFamily(def, "SansSerif");
		StyleConstants.setFontSize(regular, 12);
		
		Style s = doc.addStyle("italic", regular);
		StyleConstants.setItalic(s, true);
		
		s = doc.addStyle("bold", regular);
		StyleConstants.setBold(s, true);
		
		s = doc.addStyle("small", regular);
		StyleConstants.setFontSize(s, 10);
		
		s = doc.addStyle("large", regular);
		StyleConstants.setFontSize(s, 16);
	}
}
